import {getLocal } from '@/utils/local'
import store from '../store'
import * as types from '@/store/action-types'
class WS {
    constructor(config = {}) {//配置项
        this.url = config.url || 'vue.zhufengpeixun.cn'; 
        this.port = config.prot || 80;
      //protocol是个只读属性，用于返回服务器端选中的子协议的名字；这是一个在创建WebSocket 对象时，在参数protocols中指定的字符串
        this.protocol = config.protocol || 'ws';
        // 心跳检测 证明你还能用 30秒
        this.time = config.time || 30 * 1000;
        this.ws = null;
    }
    onOpen = () => {
        //连接建立，即握手成功触发的事件
        // 规定好发的必须是对象 对象里包含两个字段 type  data
        // websocket 是基于tcp 第一次连接靠的http 但是不能修改header
        this.ws.send(JSON.stringify({//转化为字符串
            type:'auth',
            data: getLocal('token')
        }))
    }
    onMessage = (e) => {//收到服务器消息时触发的事件
        //console.log(e.data)
        let {type,data} = JSON.parse(e.data);
        
        switch(type){
            case 'noAuth':
                console.log('没有权限');
                break;
            case 'heartCheck':
                this.checkServer();//触发检查服务器的方法，为了防止断线
                this.ws.send(JSON.stringify({type:'heartCheck'}));
                break;
                default://默认情况下时提交消息
                store.commit(types.SET_MESSAGE,data);
        }

    }
    onError = () => {//异常触发的事件
        setTimeout(() => {
            this.create();//重新调用create方法 连线的 
        }, 1000);
    }
    onClose = () => {//关闭连接触发的事件
        this.ws.close();
    }
    create() { // webworker
        this.ws = new WebSocket(`${this.protocol}://${this.url}:${this.port}`);
        this.ws.onopen = this.onOpen;
        this.ws.onmessage = this.onMessage;
        this.ws.onclose = this.onclose;
        this.ws.onerror = this.onError
    }
    checkServer(){//服务器回应
        clearTimeout(this.timer); // 防抖
        this.timer = setTimeout(() => {
            this.onClose();
            this.onError();
        }, this.time + 1000); //断线重连
    }
    send = (msg)=>{//发送信息   src/views/manager/infoPublish.vue中
      //  <el-input placeholder="请输入要发送给用户的信息" v-model="msg"></el-input>就会接受到发送的信息
        this.ws.send(JSON.stringify(msg))//在Network上可以看到发送的信息
    }
}
export default WS;